#include "stdafx.h"
//-------------------------------------------------------------------------------------------------
//ImageDataset.cpp  - Image Dataset       
//-------------------------------------------------------------------------------------------------
//FreeBSD License
//Copyright 2011 Will Stott All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are
//permitted provided that the following conditions are met:
//
//   1. Redistributions of source code must retain the above copyright notice, this list of
//      conditions and the following disclaimer.
//
//   2. Redistributions in binary form must reproduce the above copyright notice, this list
//      of conditions and the following disclaimer in the documentation and/or other materials
//      provided with the distribution.
//
//THIS SOFTWARE IS PROVIDED BY Will Stott ``AS IS'' AND ANY EXPRESS OR IMPLIED
//WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
//FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Will Stott OR
//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//The views and conclusions contained in the software and documentation are those of the
//authors and should not be interpreted as representing official policies, either expressed
//or implied, of Will Stott.
//
//----Authors--------------------------------------------------------------------------------------
//created by: will.stott@ucl.ac.uk Feb 2011
//
//----Comments-------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------

#include "ImageDataset.h"
#include "PtAnnotateShapeType.h"
#include "PtShapeType.h"
#include "EllipseShapeType.h"
#include "TinyXmlLib.h"

#include "ImageProp.h"
#include "ImagePropInteger.h"
#include "ImagePropTextLine.h"
#include "ImagePropTextLines.h"

const char * const ImageDataset::xmlHeader = "Header";
const char * const ImageDataset::xmlHeaderOwner = "Owner";
const char * const ImageDataset::xmlHeaderName = "Name";
const char * const ImageDataset::xmlHeaderDescription = "Description";
const char * const ImageDataset::xmlHeaderRepository = "Repository";
const char * const ImageDataset::xmlHeaderVersion = "Version";
const char * const ImageDataset::xmlHeaderRuntimeDir = "RuntimeDir";
const char * const ImageDataset::xmlHeaderDataQueryFile = "DataQueryFile";

const char * const ImageDataset::xmlBody = "Body";
const char * const ImageDataset::xmlImages = "Images";


ImageDataset::ImageDataset(void)
	:  _IDFPathFileName(""),
	   _SelImagePathFileName(""),
	  _pDoc('\0'),
	  _pHeader('\0'),
	  _pBody('\0'),
	  _pImages('\0'),
	  _pImageTypeUnclassified('\0'),
	  _ImageTypeIter(0),
	  _ImageObjectTypeIter(0),
	  _tempBuffLen(_TEMPBUFFLEN)
{
	  _pTempBuffer = (char *)malloc( _tempBuffLen );
}


ImageDataset::ImageDataset(const TCHAR *documentName, const char *documentTitle, const char *TopNodeName)
	: _IDFPathFileName(""),
	  _SelImagePathFileName(""),
	  _pDoc('\0'),
	  _pHeader('\0'),
	  _pBody('\0'),
	  _pImages('\0'),
	  _pImageTypeUnclassified('\0'),
	  _ImageTypeIter(0),
	  _ImageObjectTypeIter(0),
	  _tempBuffLen(_TEMPBUFFLEN)
{
	_pTempBuffer = (char *)malloc( _tempBuffLen );

	wcstombs(_pTempBuffer, documentName, _tempBuffLen );
	_IDFPathFileName = _pTempBuffer;
	_pDoc = new TiXmlDocument(_pTempBuffer);


	TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "yes" );
	_pDoc->LinkEndChild( decl );

	TiXmlComment * doctitle = new TiXmlComment( documentTitle );
	_pDoc->LinkEndChild( doctitle );

	TiXmlElement * content = new TiXmlElement( TopNodeName );
	_pDoc->LinkEndChild( content );

	_pHeader = new TiXmlElement( ImageDataset::xmlHeader );
	content->LinkEndChild( _pHeader );

	_pBody = new TiXmlElement( ImageDataset::xmlBody );
	content->LinkEndChild( _pBody );

	CreateHeader();

	CreateBody();

}


ImageDataset::~ImageDataset(void)
{
	if ( _pDoc != '\0')
		delete _pDoc; 
	if ( _pTempBuffer != '\0' )
		free(_pTempBuffer);
	ClearAllLists();
}

bool ImageDataset::CreateHeader()
{
	bool rc = false;

	if ( _pHeader != '\0')
	{
		TinyXmlLib::CreateSection (_pHeader, ImageDataset::xmlHeaderName, "" );
		TinyXmlLib::CreateSection (_pHeader, ImageDataset::xmlHeaderDescription, "" );
		TinyXmlLib::CreateSection (_pHeader, ImageDataset::xmlHeaderRepository,  "" );
		TinyXmlLib::CreateSection (_pHeader, ImageDataset::xmlHeaderVersion,  "" );
		TinyXmlLib::CreateSection (_pHeader, ImageDataset::xmlHeaderRuntimeDir,  "" );
		TinyXmlLib::CreateSection (_pHeader, ImageDataset::xmlHeaderDataQueryFile, "");	

		TiXmlElement *imageTypes = TinyXmlLib::CreateSection (_pHeader, ImageType::xmlImageTypes, "Definition of Image Types" );
		if (imageTypes)
		{
			imageTypes->SetAttribute(ImageType::xmlImageTypesName, "Ovarian US (IOTA)");
			//ImageType - Unclassified
			TiXmlElement *Unclassified = TinyXmlLib::CreateSection (imageTypes, ImageType::xmlImageType, ImageType::unclassified );

			//ImageType - Junk
			TiXmlElement *Junk = TinyXmlLib::CreateSection (imageTypes, ImageType::xmlImageType, "Junk" );
			if (Junk)
			{
				TiXmlElement *imageTypeProps = TinyXmlLib::CreateSection (Junk, ImageType::xmlImageTypeProps, "Properties for Junk image" );
				if (imageTypeProps)
				{	
					TiXmlElement *Notes = TinyXmlLib::CreateSection (imageTypeProps, ImageType::xmlImageTypeProp, "Justification" );
					if (Notes)
					{
						Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
						Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
						Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
						Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
						Notes->SetAttribute(ImageTypeProp::xmlPrompt, "Enter text to describe why this is a junk image");
						Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
					}
				}
			}

			//ImageType - LeftOvary-TS
			TiXmlElement *OvaryLOTS = TinyXmlLib::CreateSection (imageTypes, ImageType::xmlImageType, "LeftOvary-TS" );
			if (OvaryLOTS)
			{
				TiXmlElement *imageTypeProps = TinyXmlLib::CreateSection (OvaryLOTS, ImageType::xmlImageTypeProps, "Properties for Left Ovary TS image" );
				if (imageTypeProps)
				{	
					TiXmlElement *Notes = TinyXmlLib::CreateSection (imageTypeProps, ImageType::xmlImageTypeProp, "Alt-Image" );
					if (Notes)
					{
						Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
						Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
						Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
						Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
						Notes->SetAttribute(ImageTypeProp::xmlPrompt, "Enter Dicom Ref of better image");
						Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
					}
				}
			}

			//ImageType - LeftOvary-LS
			TiXmlElement *OvaryLOLS = TinyXmlLib::CreateSection (imageTypes, ImageType::xmlImageType, "LeftOvary-LS" );
			if (OvaryLOLS)
			{
				TiXmlElement *imageTypeProps = TinyXmlLib::CreateSection (OvaryLOLS, ImageType::xmlImageTypeProps, "Properties for Left Ovary LS image" );
				if (imageTypeProps)
				{	
					TiXmlElement *Notes = TinyXmlLib::CreateSection (imageTypeProps, ImageType::xmlImageTypeProp, "Alt-Image" );
					if (Notes)
					{
						Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
						Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
						Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
						Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
						Notes->SetAttribute(ImageTypeProp::xmlPrompt, "Enter Dicom Ref of better image");
						Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
					}
				}
			}

			//ImageType - RightOvary-TS
			TiXmlElement *OvaryROTS = TinyXmlLib::CreateSection (imageTypes, ImageType::xmlImageType, "RightOvary-TS" );
			if (OvaryROTS)
			{
				TiXmlElement *imageTypeProps = TinyXmlLib::CreateSection (OvaryROTS, ImageType::xmlImageTypeProps, "Properties for Right Ovary TS image" );
				if (imageTypeProps)
				{	
					TiXmlElement *Notes = TinyXmlLib::CreateSection (imageTypeProps, ImageType::xmlImageTypeProp, "Alt-Image" );
					if (Notes)
					{
						Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
						Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
						Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
						Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
						Notes->SetAttribute(ImageTypeProp::xmlPrompt, "Enter Dicom Ref of better image");
						Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
					}
				}
			}

			//ImageType - RightOvary-LS
			TiXmlElement *OvaryROLS = TinyXmlLib::CreateSection (imageTypes, ImageType::xmlImageType, "RightOvary-LS" );
			if (OvaryROLS)
			{
				TiXmlElement *imageTypeProps = TinyXmlLib::CreateSection (OvaryROLS, ImageType::xmlImageTypeProps, "Properties for Right Ovary LS image" );
				if (imageTypeProps)
				{	
					TiXmlElement *Notes = TinyXmlLib::CreateSection (imageTypeProps, ImageType::xmlImageTypeProp, "Alt-Image" );
					if (Notes)
					{
						Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
						Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
						Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
						Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
						Notes->SetAttribute(ImageTypeProp::xmlPrompt, "Enter Dicom Ref of better image");
						Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
					}
				}
			}

			//ImageType - LeftOvary-LSTS
			TiXmlElement *OvaryLOLSTS = TinyXmlLib::CreateSection (imageTypes, ImageType::xmlImageType, "LeftOvary-LS-TS" );
			if (OvaryLOLSTS)
			{
				TiXmlElement *imageTypeProps = TinyXmlLib::CreateSection (OvaryLOLSTS, ImageType::xmlImageTypeProps, "Properties for Left Ovary LS-TS image" );
				if (imageTypeProps)
				{	
					TiXmlElement *Notes = TinyXmlLib::CreateSection (imageTypeProps, ImageType::xmlImageTypeProp, "List" );
					if (Notes)
					{
						Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
						Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
						Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
						Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
						Notes->SetAttribute(ImageTypeProp::xmlPrompt, "List features in Left Ovary LS-TS image");
						Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
					}
					TiXmlElement *Quality = TinyXmlLib::CreateSection (imageTypeProps, ImageType::xmlImageTypeProp, "Quality" );
					if (Quality)
					{
						Quality->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
						Quality->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
						Quality->SetAttribute(ImageTypeProp::xmlValMin, "1");
						Quality->SetAttribute(ImageTypeProp::xmlValMax, "3");
						Quality->SetAttribute(ImageTypeProp::xmlPrompt, "Enter LO-LS-TS quality score between 1 (bad) and 3 (good)");
						Quality->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
					}
				}
				TiXmlElement *imageObjectTypes = TinyXmlLib::CreateSection (OvaryLOLSTS, ImageType::xmlImageTypeImageObjects, "Types of Objects found in Left Ovary LS-TS image" );
				if (imageObjectTypes)
				{
					TiXmlElement *Illiac = TinyXmlLib::CreateSection (imageObjectTypes, ImageType::xmlImageTypeImageObject, "Illiac Vessel" );
					if (Illiac)
					{
						Illiac->SetAttribute(ImageObjectType::attribClassName, PtAnnotateShapeType::baseClassName);
						Illiac->SetAttribute(PtAnnotateShapeType::attribNameCode, "ILL");
						Illiac->SetAttribute(PtAnnotateShapeType::attribNamePenColour, "255:125:255");
						Illiac->SetAttribute(PtAnnotateShapeType::attribNameExpertMaxObjs, "-1");
						Illiac->SetAttribute(PtAnnotateShapeType::attribNameMenuName, "Illiac Vessel");

						TiXmlElement *ImageTypeProps = TinyXmlLib::CreateSection (Illiac, ImageType::xmlImageTypeProps, "Properties of Illiac Vessel Image Object" );
						if (ImageTypeProps)
						{
							TiXmlElement *Notes = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "List" );
							if (Notes)
							{
								Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
								Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
								Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
								Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
								Notes->SetAttribute(ImageTypeProp::xmlPrompt, "Describe Illiac Vessel");
								Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
							}
							TiXmlElement *Quality = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "Quality" );
							if (Quality)
							{
								Quality->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
								Quality->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
								Quality->SetAttribute(ImageTypeProp::xmlValMin, "1");
								Quality->SetAttribute(ImageTypeProp::xmlValMax, "3");
								Quality->SetAttribute(ImageTypeProp::xmlPrompt, "Enter Illiac quality score between 1 (bad) and 3 (good)");
								Quality->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
							}
						}
					}
					TiXmlElement *OvaryLS = TinyXmlLib::CreateSection (imageObjectTypes, ImageType::xmlImageTypeImageObject, "Left Ovary LS" );
					if (OvaryLS)
					{
						OvaryLS->SetAttribute(ImageObjectType::attribClassName, PtShapeType::baseClassName);
						OvaryLS->SetAttribute(PtShapeType::attribNameCode, "LLS");
						OvaryLS->SetAttribute(PtShapeType::attribNamePenColour, "255:255:255");
						OvaryLS->SetAttribute(PtShapeType::attribNameExpertMaxObjs, "1");
						OvaryLS->SetAttribute(PtShapeType::attribNameMenuName, "Left Ovary LS");

						TiXmlElement *ImageTypeProps = TinyXmlLib::CreateSection (OvaryLS, ImageType::xmlImageTypeProps, "Properties of Left Ovary LS Image Object" );
						if (ImageTypeProps)
						{
							TiXmlElement *Notes = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "List" );
							if (Notes)
							{
								Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
								Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
								Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
								Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
								Notes->SetAttribute(ImageTypeProp::xmlPrompt, "List features in Left Ovary LS image");
								Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
							}
							TiXmlElement *Quality = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "Quality" );
							if (Quality)
							{
								Quality->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
								Quality->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
								Quality->SetAttribute(ImageTypeProp::xmlValMin, "1");
								Quality->SetAttribute(ImageTypeProp::xmlValMax, "3");
								Quality->SetAttribute(ImageTypeProp::xmlPrompt, "Enter LO-LS quality score between 1 (bad) and 3 (good)");
								Quality->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
							}
						}
					}
					TiXmlElement *OvaryTS = TinyXmlLib::CreateSection (imageObjectTypes, ImageType::xmlImageTypeImageObject, "Left Ovary TS" );
					if (OvaryTS)
					{
						OvaryTS->SetAttribute(ImageObjectType::attribClassName, PtShapeType::baseClassName);
						OvaryTS->SetAttribute(PtShapeType::attribNameCode, "LTS");
						OvaryTS->SetAttribute(PtShapeType::attribNamePenColour, "255:0:0");
						OvaryTS->SetAttribute(PtShapeType::attribNameExpertMaxObjs, "2");
						OvaryTS->SetAttribute(PtShapeType::attribNameMenuName, "Left Ovary TS");

						TiXmlElement *ImageTypeProps = TinyXmlLib::CreateSection (OvaryTS, ImageType::xmlImageTypeProps, "Properties of Left Ovary TS Image Object" );
						if (ImageTypeProps)
						{
							TiXmlElement *Notes = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "List" );
							if (Notes)
							{
								Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
								Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
								Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
								Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
								Notes->SetAttribute(ImageTypeProp::xmlPrompt, "Features in Left Ovary TS image");
								Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
							}
							TiXmlElement *Quality = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "Quality" );
							if (Quality)
							{
								Quality->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
								Quality->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
								Quality->SetAttribute(ImageTypeProp::xmlValMin, "1");
								Quality->SetAttribute(ImageTypeProp::xmlValMax, "3");
								Quality->SetAttribute(ImageTypeProp::xmlPrompt, "Enter LO-TS quality score between 1 (bad) and 3 (good)");
								Quality->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
							}
						}
					}
					TiXmlElement *InclusionCyst = TinyXmlLib::CreateSection (imageObjectTypes, ImageType::xmlImageTypeImageObject, "LO-InclusionCyst" );
					if (InclusionCyst)
					{
						InclusionCyst->SetAttribute(ImageObjectType::attribClassName, PtShapeType::baseClassName);
						InclusionCyst->SetAttribute(PtShapeType::attribNameCode, "LIC");
						InclusionCyst->SetAttribute(PtShapeType::attribNamePenColour, "0:255:0");
						InclusionCyst->SetAttribute(PtShapeType::attribNameExpertMaxObjs, "-1");
						InclusionCyst->SetAttribute(PtShapeType::attribNameMenuName, "LO Inclusion Cyst");

						TiXmlElement *ImageTypeProps = TinyXmlLib::CreateSection (InclusionCyst, ImageType::xmlImageTypeProps, "Properties of Left Ovary IC Image Object" );
						if (ImageTypeProps)
						{
							TiXmlElement *Quality = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "Quality" );
							if (Quality)
							{
								Quality->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
								Quality->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
								Quality->SetAttribute(ImageTypeProp::xmlValMin, "1");
								Quality->SetAttribute(ImageTypeProp::xmlValMax, "3");
								Quality->SetAttribute(ImageTypeProp::xmlPrompt, "Enter LO IC quality score between 1 (bad) and 3 (good)");
								Quality->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
							}
						}
					}
					//ImageType - LeftOvary-TS - SimpleCyst
					TiXmlElement *SimpleCyst = TinyXmlLib::CreateSection (imageObjectTypes, ImageType::xmlImageTypeImageObject, "LO-SimpleCyst" );
					if (SimpleCyst)
					{
						SimpleCyst->SetAttribute(ImageObjectType::attribClassName, EllipseShapeType::baseClassName);
						SimpleCyst->SetAttribute(EllipseShapeType::attribNameCode, "LSC");
						SimpleCyst->SetAttribute(EllipseShapeType::attribNamePenColour, "0:0:255");
						SimpleCyst->SetAttribute(EllipseShapeType::attribNameExpertMaxObjs, "-1");
						SimpleCyst->SetAttribute(EllipseShapeType::attribNameMenuName, "LO Simple Cyst");

						TiXmlElement *ImageTypeProps = TinyXmlLib::CreateSection (SimpleCyst, ImageType::xmlImageTypeProps, "Properties of this Left Ovary Simple Cyst Image Object" );
						if (ImageTypeProps)
						{
							TiXmlElement *Texture = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "Texture" );
							if (Texture)
							{
								Texture->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
								Texture->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
								Texture->SetAttribute(ImageTypeProp::xmlValMin, "1");
								Texture->SetAttribute(ImageTypeProp::xmlValMax, "3");
								Texture->SetAttribute(ImageTypeProp::xmlPrompt, "Enter LO Simple Cyst texture score between 1 (clear) and 3 (mottled)");
								Texture->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
							}
						}
					}
				}
			}

			//ImageType - RightOvary-LSTS
			TiXmlElement *OvaryROLSTS = TinyXmlLib::CreateSection (imageTypes, ImageType::xmlImageType, "RightOvary-LS-TS" );
			if (OvaryROLSTS)
			{
				TiXmlElement *imageTypeProps = TinyXmlLib::CreateSection (OvaryROLSTS, ImageType::xmlImageTypeProps, "Properties for Right Ovary LS-TS image" );
				if (imageTypeProps)
				{	
					TiXmlElement *Notes = TinyXmlLib::CreateSection (imageTypeProps, ImageType::xmlImageTypeProp, "List" );
					if (Notes)
					{
						Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
						Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
						Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
						Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
						Notes->SetAttribute(ImageTypeProp::xmlPrompt, "List features in Right Ovary LS-TS image");
						Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
					}
					TiXmlElement *Quality = TinyXmlLib::CreateSection (imageTypeProps, ImageType::xmlImageTypeProp, "Quality" );
					if (Quality)
					{
						Quality->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
						Quality->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
						Quality->SetAttribute(ImageTypeProp::xmlValMin, "1");
						Quality->SetAttribute(ImageTypeProp::xmlValMax, "3");
						Quality->SetAttribute(ImageTypeProp::xmlPrompt, "Enter RO-LS-TS quality score between 1 (bad) and 3 (good)");
						Quality->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
					}
				}
				TiXmlElement *imageObjectTypes = TinyXmlLib::CreateSection (OvaryROLSTS, ImageType::xmlImageTypeImageObjects, "Types of Objects found in Right Ovary LS-TS image" );
				if (imageObjectTypes)
				{	
					TiXmlElement *OvaryLS = TinyXmlLib::CreateSection (imageObjectTypes, ImageType::xmlImageTypeImageObject, "Right Ovary LS" );
					if (OvaryLS)
					{
						OvaryLS->SetAttribute(ImageObjectType::attribClassName, PtShapeType::baseClassName);
						OvaryLS->SetAttribute(PtShapeType::attribNameCode, "RLS");
						OvaryLS->SetAttribute(PtShapeType::attribNamePenColour, "255:0:255");
						OvaryLS->SetAttribute(PtShapeType::attribNameExpertMaxObjs, "2");
						OvaryLS->SetAttribute(PtShapeType::attribNameMenuName, "Right Ovary LS");

						TiXmlElement *ImageTypeProps = TinyXmlLib::CreateSection (OvaryLS, ImageType::xmlImageTypeProps, "Properties of Right Ovary LS Image Object" );
						if (ImageTypeProps)
						{
							TiXmlElement *Notes = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "List" );
							if (Notes)
							{
								Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
								Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
								Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
								Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
								Notes->SetAttribute(ImageTypeProp::xmlPrompt, "List features in Right Ovary LS Image Object");
								Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
							}
							TiXmlElement *Quality = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "Quality" );
							if (Quality)
							{
								Quality->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
								Quality->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
								Quality->SetAttribute(ImageTypeProp::xmlValMin, "1");
								Quality->SetAttribute(ImageTypeProp::xmlValMax, "3");
								Quality->SetAttribute(ImageTypeProp::xmlPrompt, "Enter RO-LS quality score between 1 (bad) and 3 (good)");
								Quality->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
							}
						}
					}
					TiXmlElement *OvaryTS = TinyXmlLib::CreateSection (imageObjectTypes, ImageType::xmlImageTypeImageObject, "Right Ovary TS" );
					if (OvaryTS)
					{
						OvaryTS->SetAttribute(ImageObjectType::attribClassName, PtShapeType::baseClassName);
						OvaryTS->SetAttribute(PtShapeType::attribNameCode, "RTS");
						OvaryTS->SetAttribute(PtShapeType::attribNamePenColour, "255:255:0");
						OvaryTS->SetAttribute(PtShapeType::attribNameExpertMaxObjs, "1");
						OvaryTS->SetAttribute(PtShapeType::attribNameMenuName, "Right Ovary TS");

						TiXmlElement *ImageTypeProps = TinyXmlLib::CreateSection (OvaryTS, ImageType::xmlImageTypeProps, "Properties of Right Ovary TS Image Object" );
						if (ImageTypeProps)
						{
							TiXmlElement *Notes = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "List" );
							if (Notes)
							{
								Notes->SetAttribute(ImageTypeProp::xmlType, ImagePropTextLine::className);
								Notes->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSLEdit);
								Notes->SetAttribute(ImageTypeProp::xmlValMin, "0");
								Notes->SetAttribute(ImageTypeProp::xmlValMax, "100");
								Notes->SetAttribute(ImageTypeProp::xmlPrompt, "List features in Right Ovary TS");
								Notes->SetAttribute(ImageTypeProp::xmlDefaultValue, "...");
							}
							TiXmlElement *Quality = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "Quality" );
							if (Quality)
							{
								Quality->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
								Quality->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
								Quality->SetAttribute(ImageTypeProp::xmlValMin, "1");
								Quality->SetAttribute(ImageTypeProp::xmlValMax, "3");
								Quality->SetAttribute(ImageTypeProp::xmlPrompt, "Enter RO-TS quality score between 1 (bad) and 3 (good)");
								Quality->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
							}
						}
					}
					TiXmlElement *InclusionCyst = TinyXmlLib::CreateSection (imageObjectTypes, ImageType::xmlImageTypeImageObject, "RO-InclusionCyst" );
					if (InclusionCyst)
					{
						InclusionCyst->SetAttribute(ImageObjectType::attribClassName, PtShapeType::baseClassName);
						InclusionCyst->SetAttribute(PtShapeType::attribNameCode, "RIC");
						InclusionCyst->SetAttribute(PtShapeType::attribNamePenColour, "255:125:0");
						InclusionCyst->SetAttribute(PtShapeType::attribNameExpertMaxObjs, "-1");
						InclusionCyst->SetAttribute(PtShapeType::attribNameMenuName, "RO Inclusion Cyst");

						TiXmlElement *ImageTypeProps = TinyXmlLib::CreateSection (InclusionCyst, ImageType::xmlImageTypeProps, "Properties of RO Inclusion Cyst Image Object" );
						if (ImageTypeProps)
						{
							TiXmlElement *Quality = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "Quality" );
							if (Quality)
							{
								Quality->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
								Quality->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
								Quality->SetAttribute(ImageTypeProp::xmlValMin, "1");
								Quality->SetAttribute(ImageTypeProp::xmlValMax, "3");
								Quality->SetAttribute(ImageTypeProp::xmlPrompt, "Enter ROIC quality score between 1 (bad) and 3 (good)");
								Quality->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
							}
						}
					}
					TiXmlElement *SimpleCyst = TinyXmlLib::CreateSection (imageObjectTypes, ImageType::xmlImageTypeImageObject, "RO-SimpleCyst" );
					if (SimpleCyst)
					{
						SimpleCyst->SetAttribute(ImageObjectType::attribClassName, EllipseShapeType::baseClassName);
						SimpleCyst->SetAttribute(EllipseShapeType::attribNameCode, "RSC");
						SimpleCyst->SetAttribute(EllipseShapeType::attribNamePenColour, "255:125:255");
						SimpleCyst->SetAttribute(EllipseShapeType::attribNameExpertMaxObjs, "-1");
						SimpleCyst->SetAttribute(EllipseShapeType::attribNameMenuName, "RO Simple Cyst");

						TiXmlElement *ImageTypeProps = TinyXmlLib::CreateSection (SimpleCyst, ImageType::xmlImageTypeProps, "Properties of RO Simple Cyst Image Object" );
						if (ImageTypeProps)
						{
							TiXmlElement *Texture = TinyXmlLib::CreateSection (ImageTypeProps, ImageType::xmlImageTypeProp, "Texture" );
							if (Texture)
							{
								Texture->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
								Texture->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
								Texture->SetAttribute(ImageTypeProp::xmlValMin, "1");
								Texture->SetAttribute(ImageTypeProp::xmlValMax, "3");
								Texture->SetAttribute(ImageTypeProp::xmlPrompt, "Enter RO Simple Cyst texture score between 1 (clear) and 3 (mottled)");
								Texture->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
							}
						}
					}
				}
			}
			//ImageType - Endometrium
			TiXmlElement *Endometrium = TinyXmlLib::CreateSection (imageTypes, ImageType::xmlImageType, "Endometrium" );
			if (Endometrium)
			{
				TiXmlElement *imageTypeProps = TinyXmlLib::CreateSection (Endometrium, ImageType::xmlImageTypeProps, "Properties for Endometrium image" );
				if (imageTypeProps)
				{	
					TiXmlElement *Thickness = TinyXmlLib::CreateSection (imageTypeProps, ImageType::xmlImageTypeProp, "Thickness" );
					if (Thickness)
					{
						Thickness->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
						Thickness->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
						Thickness->SetAttribute(ImageTypeProp::xmlValMin, "1");
						Thickness->SetAttribute(ImageTypeProp::xmlValMax, "15");
						Thickness->SetAttribute(ImageTypeProp::xmlPrompt, "Enter thickness between 1 and 15");
						Thickness->SetAttribute(ImageTypeProp::xmlDefaultValue, "4");
					}
					TiXmlElement *Quality = TinyXmlLib::CreateSection (imageTypeProps, ImageType::xmlImageTypeProp, "Quality" );
					if (Quality)
					{
						Quality->SetAttribute(ImageTypeProp::xmlType, ImagePropInteger::className);
						Quality->SetAttribute(ImageTypeProp::xmlControl, ImageProp::xmlCtrlSpin);
						Quality->SetAttribute(ImageTypeProp::xmlValMin, "1");
						Quality->SetAttribute(ImageTypeProp::xmlValMax, "3");
						Quality->SetAttribute(ImageTypeProp::xmlPrompt, "Enter quality score between 1 (bad) and 3 (good)");
						Quality->SetAttribute(ImageTypeProp::xmlDefaultValue, "2");
					}
				}
			}
		}
		rc = true;
	}
	return rc;
}

bool ImageDataset::CreateBody()
{
	bool rc = false;

	if ( _pBody != '\0')
	{
		if ( (_pImages = TinyXmlLib::CreateSection (_pBody, ImageDataset::xmlImages,  "collection of images for dataset" )) != '\0')
			rc = true;
	}
	return rc;
}

TiXmlElement *ImageDataset::IterateImages(TiXmlElement *child)
{
	TiXmlElement *rc = '\0';

	if (IsValidBody())
	{
		TiXmlNode *node = child;
		while( node = _pImages->IterateChildren( ImageProps::xmlImage, child ) )
		{
			if (node->Type() == TiXmlNode::TINYXML_ELEMENT)
			{
				rc = (TiXmlElement *)node;
				break;
			}
		}
	}
	return rc;
}

const char *ImageDataset::GetHeaderValue(const char *Label)
{
	const char *rc = '\0';

	if (IsValidHeader())
	{
		for( TiXmlNode *child = _pHeader->FirstChild(); child; child = child->NextSibling() )
		{
			if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
			{
				TiXmlElement *xmlHeaderItem = (TiXmlElement *)child;
				if (xmlHeaderItem != '\0')
				{
					const char *val = xmlHeaderItem->Value();
					if ( (val != '\0') && (strcmp(val, Label) == 0 ))
					{
						rc = ImageDataset::GetXmlAttribute(xmlHeaderItem, "Data", "");
						break;
					}
				}
			}
		}
	}
	return rc;
}

bool ImageDataset::SetHeaderValue(const char *Label, const char *Value)
{
	bool rc = false;

	if (IsValidHeader())
	{
		for( TiXmlNode *child = _pHeader->FirstChild(); child; child = child->NextSibling() )
		{
			if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
			{
				TiXmlElement *xmlHeaderItem = (TiXmlElement *)child;
				if (xmlHeaderItem != '\0')
				{
					const char *val = xmlHeaderItem->Value();
					if ( (val != '\0') && (strcmp(val, Label) == 0 ))
					{
						xmlHeaderItem->SetAttribute("Data", Value);
						rc = true;
						break;
					}
				}
			}
		}
	}
	return rc;
}

const char *ImageDataset::GetRuntimeDir()
{
	const char *rc = '\0';

	rc = GetHeaderValue(ImageDataset::xmlHeaderRuntimeDir);

	//if (IsValidHeader())
	//{
	//	TiXmlNode *pNode = _pHeader->FirstChild(ImageDataset::xmlHeaderRuntimeDir);
	//	if (pNode != '\0')
	//	{
	//		TiXmlElement *pElement = pNode->ToElement();
	//		if (pElement != '\0')
	//			rc = pElement->GetText();
	//	}
	//}
	return rc;
}

void ImageDataset::SetSelImagePathFileName(const char *DicomRef)
{
	if (DicomRef == '\0')
	{
		_SelImagePathFileName = "";
	}
	else
	{
		_SelImagePathFileName = GetRuntimeDir();
		_SelImagePathFileName += "\\";
		_SelImagePathFileName += DicomRef;
		_SelImagePathFileName += ".bmp";
	}
}

bool ImageDataset::AddImage(const TCHAR *dicomRef)
{
	bool rc = false;

	if ( IsValidBody())
	{
		wcstombs(_pTempBuffer, dicomRef, _tempBuffLen );
		TiXmlElement *image = TinyXmlLib::CreateSection (_pImages, ImageProps::xmlImage, _pTempBuffer );
		rc = true;
	}

	return rc;
}

bool ImageDataset::SaveFile(const TCHAR *PathFileName) 
{ 	
	bool rc = false;

	if ( _pDoc != '\0')
	{
		if ( PathFileName )
		{
			wcstombs(_pTempBuffer, PathFileName, _tempBuffLen );
			rc = _pDoc->SaveFile(_pTempBuffer);
		}
		else
			rc = _pDoc->SaveFile();
	}
	return rc;
}

bool ImageDataset::LoadFile(const TCHAR *PathFileName, ResourceList &resourceList)  //todo - identify the elements being read
{
	bool rc = false;

	if ( _pTempBuffer ) 
	{
		TiXmlDocument *pDocTemp = _pDoc;
		TiXmlElement *pHeaderTemp =	_pHeader;
		TiXmlElement *pBodyTemp =_pBody;
		TiXmlElement *pImagesTemp =_pImages;

		_pDoc = new TiXmlDocument();

		wcstombs(_pTempBuffer, PathFileName, _tempBuffLen );
		_IDFPathFileName = _pTempBuffer;

		if ( _pDoc->LoadFile(_pTempBuffer)) 
		{
			TiXmlElement * pContent = _pDoc->FirstChildElement();
			if (pContent != '\0')
			{
				if ((_pHeader = pContent->FirstChildElement()) != '\0')
				{
					TiXmlNode *pNode = '\0';
					while ((pNode = _pHeader->NextSibling()) != '\0')
					{
						if (pNode->Type() == TiXmlNode::TINYXML_ELEMENT)
						{
							_pBody = dynamic_cast<TiXmlElement *>(pNode);
							if (_pBody != '\0')
							{
								if ((_pImages = _pBody->FirstChildElement()) != '\0')
								{
									rc = true;
								}
							}
							if ((rc == true) && (pDocTemp != '\0'))
							{
								delete pDocTemp;
								pDocTemp = '\0';
							}
							break;
						}
					}
				}
			}
		}

		if (rc == true)
			InitImageTypes(resourceList);
		else
		{
			if ( _pDoc != '\0')
				delete _pDoc;
			_pDoc = pDocTemp;
			_pHeader = pHeaderTemp;
			_pBody = pBodyTemp;
			_pImages = pImagesTemp;
		}
	}
	return rc;
}

bool ImageDataset::LoadPropertiesForImage(const char *DicomRef, ImageProps *pSelImageProps, ImageObjectTypeTool *pSelTool)
{
	bool rc = false;

//!!!!!!!!!!!!!!!
#ifdef _DEBUG
	MxUtils::OutputDebugMsg("ImageDataset::LoadPropertiesForImage()", "load props for given image from XML file" );
#endif
//!!!!!!!!!!!!!!!

	if ( IsValidBody() && (pSelImageProps != '\0'))
	{
		SetSelImagePathFileName('\0');
		pSelImageProps->ResetToDefaults();

		if (ImageProps::IsValidDicomRef(DicomRef))
		{
			for( TiXmlNode *child = _pImages->FirstChild(); child; child = child->NextSibling() )
			{
				if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
				{
					TiXmlElement *xmlImage = (TiXmlElement *)child;
					if (xmlImage)
					{
						const char *val = xmlImage->Value();
						if ( (val != '\0') && (strcmp(val, ImageProps::xmlImage) == 0 ))
						{
							if ( strcmp(xmlImage->GetText(), DicomRef) == 0 )
							{
								SetSelImagePathFileName(DicomRef);

								if ( pSelImageProps->SetDicomRef(DicomRef))
								{		//load properties for this image
									if ( pSelImageProps->LoadProperties(xmlImage, GetImageType(GetImageTypeName(xmlImage)), pSelTool) )
									{
										rc = true;			//load image objects for this image
										for( TiXmlNode *gchild = xmlImage->FirstChild(); gchild; gchild = gchild->NextSibling() )
										{
											if (gchild->Type() == TiXmlNode::TINYXML_ELEMENT)
											{
												TiXmlElement *imageObjectXml = dynamic_cast<TiXmlElement *>(gchild);
												if (imageObjectXml)
												{			
													if ( pSelImageProps->LoadImageObject(imageObjectXml, LookupImageObjectType(imageObjectXml->Attribute("Type"))) == false)
													{
														rc = false;
														break;
													}
												}
											}
										}
									}
								}
								break;
							}
						}
					}
				}
			}
			if ( rc ==  false)
			{
				pSelImageProps->ResetToDefaults();
				SetSelImagePathFileName('\0');
			}
		}
	}
	return rc;
}


bool ImageDataset::SavePropertiesForImage(ImageProps *pSelImageProps)
{
	bool rc = true;

//!!!!!!!!!!!!!!!
#ifdef _DEBUG
	MxUtils::OutputDebugMsg("ImageDataset::SavePropertiesForImage()", "save in XML file the props of selected image [%s]  - TODO check props have changed before updating xml", ((pSelImageProps != '\0') && (pSelImageProps->GetDicomRef() != '\0')) ? pSelImageProps->GetDicomRef() : "pSelImageProps or pSelImageProps->GetDicomRef() is null" );
#endif
//!!!!!!!!!!!!!!!

	if ( IsValidBody() && (pSelImageProps != '\0'))
	{
		if (pSelImageProps->IsValidSelectedImage())
		{
			rc = false;

			for( TiXmlNode *child = _pImages->FirstChild(); child; child = child->NextSibling() )
			{
				if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
				{
					TiXmlElement *imageXml = (TiXmlElement *)child;
					if (imageXml)
					{
						const char *val = imageXml->Value();
						if ( (val != '\0') && (strcmp(val, ImageProps::xmlImage) == 0 ))
						{
							if ( strcmp(imageXml->GetText(), pSelImageProps->GetDicomRef()) == 0 )
							{						// this is the xmlelement for this Image
								if (pSelImageProps->SaveProperties(imageXml) == true)
								{
									rc = true;
													// save the various image objects of each possible type for this Image
									ImageObjectType *pImageObjectType = StartImageObjectTypeIter();
									while ((pImageObjectType = GetNextImageObjectType()) != '\0')
									{
										if ( pSelImageProps->SaveImageObjects(imageXml, pImageObjectType) == false)
										{
											rc = false;
											break;
										}
									}				//remove any XMLElements corresponding to ImageObjects now deleted
									while (pSelImageProps->DeleteNextEmptyImageObjectXml(imageXml));	
									break;
								}
							}
						}
					}
				}
			}
		}
	}
	return rc;
}

ImageType *ImageDataset::GetImageType(const char *name)
{ 
	ImageType *rc = '\0';

	if ( name != '\0' )
	{
		std::string typeName(name);
		size_t cnt = _ImageTypes.size();
		for (size_t x = 0; x < cnt; x++)
		{
			if (typeName == _ImageTypes[x]->GetName() )
			{
				rc = _ImageTypes[x];
				break;
			}
		}
		if ( rc == '\0' ) 
			rc = _pImageTypeUnclassified;
	}
	return rc;
}

const char *ImageDataset::GetImageTypeName(TiXmlElement *pImageXml )
{
	const char *rc = '\0';

	if ( pImageXml != '\0') 
	{
		std::string elementType = pImageXml->Value();
		if (elementType == ImageProps::xmlImage )
		{
			rc = pImageXml->Attribute(ImageType::xmlImageType);
			if (rc == '\0') 
				rc = ImageType::unclassified; 
		}
	}
	return rc;
}

//............................................................................................
//static member functions
//............................................................................................


bool ImageDataset::SetXmlAttribute(TiXmlElement *pXmlElement, const char *Name, const char *Value)
{
	bool rc = false;

	if (( pXmlElement != '\0') && (Name != '\0') && (Value != '\0'))
	{
		const char *pValueXml = pXmlElement->Attribute(Name);
		if (pValueXml == '\0') 
			pXmlElement->SetAttribute(Name, Value);			//don't exist, so create
		else
		{
			std::string existingValueXml = pValueXml;
			if (existingValueXml != Value)
				pXmlElement->SetAttribute(Name, Value);		//exists, but value has changed so update
		}
		rc = true;
	}
	return rc;
}

const char *ImageDataset::GetXmlAttribute(TiXmlElement *pXmlElement, const char *Name, const char *defaultVal)
{
	const char *rc = defaultVal;

	if (( pXmlElement != '\0') && (Name != '\0') )
	{
		const char *pValueXml = pXmlElement->Attribute(Name);
		if (pValueXml == '\0') 
			pXmlElement->SetAttribute(Name, defaultVal);			//don't exist, so create and set default value
		else
			rc = pValueXml;
	}

	return rc;
}

bool ImageDataset::DeleteAllSubSections (TiXmlElement *pSectionXml, const char *subSectionName )
{
	bool rc = false;

	if ( pSectionXml != '\0')
	{
		rc = true;

		for( TiXmlNode *gchild = pSectionXml->FirstChild(); gchild; gchild = gchild->NextSibling() )
		{
			if (gchild->Type() == TiXmlNode::TINYXML_ELEMENT)
			{
				TiXmlElement *pSubsectionXml = dynamic_cast<TiXmlElement *>(gchild);
				if (pSubsectionXml)
				{
					std::string imageObjectNameXml = pSubsectionXml->GetText();
					if (imageObjectNameXml == subSectionName)
					{
						if ((rc = pSectionXml->RemoveChild(gchild)) == false)
							break;
					}
				}
			}
		}
	}
	return rc;
}

//XML elements must follow these naming rules:
// Names can contain letters, numbers, and other characters
// Names cannot start with a number or punctuation character
// Names cannot start with the letters xml (or XML, or Xml, etc)
// Names cannot contain spaces

const char *ImageDataset::MakeWellFormedAttributeName(std::string &AttribName)
{
	using namespace std;

	basic_string <char>::size_type  index;

	if (AttribName.length() == 0 )
		AttribName = "NullAttrib";
	else
	{
		char p = AttribName[0];
		if ( (p == 'x') || (p == 'x'))
			AttribName[0] = 'Y';		//avoid Xml
		if (isalpha(p) == false)
			AttribName[0] = 'Z';		//avoid numbers or punctuation

		string name;
		while ((index = AttribName.find(" ", 0)) != string::npos)
		{
			name = AttribName;
			AttribName = name.replace(index,1,"-");
		}
		if ( AttribName.length() > ImageProps::NameLengthMax)
			AttribName.resize(ImageProps::NameLengthMax);
	}
	return AttribName.c_str();
}

//............................................................................................
//private member functions
//............................................................................................

bool ImageDataset::ClearAllLists()
{
	bool rc = false;

	size_t cnt = _ImageTypes.size();
	if (cnt > 0 )
	{
		for (size_t x = 0; x < cnt; x++)
			delete  _ImageTypes[x];
		_ImageTypes.clear();
		rc = true;
	}

	return rc;
}

void ImageDataset::InitImageTypes(ResourceList &resourceList)
{

	if ( _pHeader )
	{
		std::string unclassified = ImageType::unclassified;
		ImageType *pImageType = ImageType::CreateImageType('\0', resourceList); //, this);
		if ((pImageType != '\0') && (unclassified == pImageType->GetName()))
		{
			_pImageTypeUnclassified = pImageType;
			if ( AddImageType(pImageType) == false)	//always add unclassified
				delete pImageType;
		}

		for( TiXmlNode *child = _pHeader->FirstChild(); child; child = child->NextSibling() )
		{
			if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
			{
				TiXmlElement *imageTypeList = dynamic_cast<TiXmlElement *>(child);
				if (imageTypeList != '\0')
				{
					std::string val = imageTypeList->Value();
					if ( val == ImageType::xmlImageTypes)
					{
						for( TiXmlNode *child = imageTypeList->FirstChild(); child; child = child->NextSibling() )
						{
							if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
							{
								TiXmlElement *xmlImageType = dynamic_cast<TiXmlElement *>(child);
								if ( xmlImageType != '\0' )
								{
									val = xmlImageType->Value();
									if ( val == ImageType::xmlImageType)
									{
										if ((pImageType = ImageType::CreateImageType(xmlImageType, resourceList)) != '\0')
										{
											if ( AddImageType(pImageType) == false)	
												delete pImageType;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	return;
}


ImageObjectType *ImageDataset::GetImageObjectTypeForMenuId( int Id)
{
	ImageObjectType *rc = '\0';

	size_t cnt = _ImageTypes.size();
	for (size_t x = 0; x < cnt; x++)
	{
		if ((rc = _ImageTypes[x]->GetImageObjectTypeForMenuId(Id)) != '\0')
		{
			break;
		}
	}

	return rc;
}


ImageObjectType *ImageDataset::StartImageObjectTypeIter()
{
	_ImageTypeIter = 0;
	_ImageObjectTypeIter = 0;

	return '\0';
}

ImageObjectType *ImageDataset::GetNextImageObjectType()
{
	ImageObjectType *rc = '\0';

	while ( (rc == '\0') && (_ImageTypeIter < _ImageTypes.size()))
	{
		if ( _ImageObjectTypeIter < _ImageTypes[_ImageTypeIter]->GetImageObjectTypeCnt())
		{
			rc = _ImageTypes[_ImageTypeIter]->GetImageObjectType(_ImageObjectTypeIter);

			_ImageObjectTypeIter++;
		}
		else
		{
			_ImageObjectTypeIter = 0;
			_ImageTypeIter++;
		}
	}
	return rc;
}

ImageObjectType *ImageDataset::LookupImageObjectType (const char *name)
{
	ImageObjectType *rc = '\0';

	if ( name != '\0' )
	{
		size_t cnt = _ImageTypes.size();
		for (size_t x = 0; x < cnt; x++)
		{
			if ((rc = _ImageTypes[x]->LookupImageObjectType(name)) != '\0' )
			{
				break;
			}
		}
	}
	return rc;
}


ImageType *ImageDataset::LookupImageType (const char *name)
{
	ImageType *rc = '\0';

	if ( name != '\0' )
	{
		std::string typeName(name);
		size_t cnt = _ImageTypes.size();
		for (size_t x = 0; x < cnt; x++)
		{
			if (typeName ==  _ImageTypes[x]->GetName() )
			{
				rc = _ImageTypes[x];
				break;
			}
		}
	}
	return rc;
}

bool ImageDataset::AddImageType (ImageType *pImageType )
{
	bool rc = false;

	if ( LookupImageType (pImageType->GetName()) == '\0')
	{
		_ImageTypes.push_back(pImageType);
		rc = true;
	}

	return rc;
}


//-------------------------------------------------------------------------------------------------
//			E N D   O F   F I L E
//-------------------------------------------------------------------------------------------------
